package com.baofu.paycore.biz.tools;

import com.baofu.account.service.facade.enums.ReceiptStatusEnum;
import com.baofu.account.service.facade.model.result.AccountBaseResDTO;
import com.baofu.clear.service.facade.enums.ClearStatusEnum;
import com.baofu.clear.service.facade.model.resp.PayRespDTO;
import com.baofu.paycore.biz.external.clear.model.ClearFundResBO;
import com.baofu.paycore.common.exception.ClearErrorCode;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.common.utils.ExceptionUtil;
import com.baofu.paycore.manager.model.AccountRespBO;
import com.baofu.paycore.manager.model.UnFreezeTransferRespBO;
import com.baofu.paycore.manager.model.UnFreezeWithdrawRespBO;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import com.google.common.base.Objects;
import com.system.commons.exception.BizServiceException;
import com.system.commons.result.Result;
import lombok.extern.slf4j.Slf4j;

/**
 * 远程调用 响应校验
 *
 * <p>
 *   1.判断响应是否为空
 *   2.判断响应是否成功
 * </p>
 * User: xin deng  Date: 16/7/5 ProjectName: paycore Version: 1.0
 */
@Slf4j
public class AssertResponse {

    /**
     * 判断响应是否为空
     *
     * @param result        响应
     */
    public static <T> void assertResNotNull(Result<T> result) {
        if(result == null){
            log.error("接口调用响应为空");
            throw new BizServiceException(PayCoreErrorCode.REMOTE_SERVICE_INVOKE_EXCEPTION,
                    PayCoreErrorCode.REMOTE_SERVICE_INVOKE_EXCEPTION.getErrorDesc());
        }
    }

    /**
     * 判断响应是否成功
     *
     * @param result        响应
     */
    public static <T> boolean assertResSuccess(Result<T> result) {

        return result.isSuccess() && result.getResult() != null;
    }

    /**
     * 判断响应是否成功
     *
     * @param result        响应
     */
    public static <T extends AccountBaseResDTO> PayStatusEnums assertAccountSuccess(Result<T> result) {
        boolean flag = result.isSuccess();//是否调用成功

        if(flag){
            AccountBaseResDTO baseResDTO =  result.getResult();
            if(baseResDTO == null){
                log.error("账务result 为空:{}",result);
                return PayStatusEnums.INIT;
            }
            String status = baseResDTO.getTradeStatus();
            if(Objects.equal(ReceiptStatusEnum.SUCCESS.getCode(), status) ||
                    Objects.equal(ReceiptStatusEnum.PAYER_OVER.getCode(), status) ||
                    Objects.equal(ReceiptStatusEnum.ASYNC_ALL.getCode(), status)){
                return PayStatusEnums.SUCCESS;
            }
            if(Objects.equal(ReceiptStatusEnum.FAILURE.getCode(), status)){
                return PayStatusEnums.FAIL;
            }
            if(Objects.equal(ReceiptStatusEnum.INITIAL.getCode(),status)){
                return  PayStatusEnums.INIT;
            }
            log.error("账务状态有误:{}",status);
            return PayStatusEnums.INIT;
        }
        //账务不明确状态,默认处理中
        return PayStatusEnums.INIT;
    }


    /**
     * 组装账务调用响应对象
     *
     * @param result        result
     * @param reqNo         请求流水号
     * @return              ResponseBO
     */
    public static AccountRespBO getResponseBO(Result result, String reqNo) {
        AccountRespBO responseBO = new AccountRespBO();
        responseBO.setRequestNo(reqNo);
        buildResponse(responseBO, result);
        log.debug("账务调用响应：{}", responseBO);
        return responseBO;
    }

    /**
     * 组装账务解冻转账调用响应对象
     *
     * @param result        result
     * @param reqNo         请求流水号
     * @return              ResponseBO
     */
    public static UnFreezeTransferRespBO getUnFreezeTransferRespBO(Result result, String reqNo) {
        UnFreezeTransferRespBO unFreezeTransferRespBO = new UnFreezeTransferRespBO();
        unFreezeTransferRespBO.setRequestNo(reqNo);
        buildResponse(unFreezeTransferRespBO, result);
        log.debug("账务调用响应：{}", unFreezeTransferRespBO);
        return unFreezeTransferRespBO;
    }

    /**
     * 组装账务解冻提现调用响应对象
     *
     * @param result        result
     * @param reqNo         请求流水号
     * @return              ResponseBO
     */
    public static UnFreezeWithdrawRespBO getUnFreezeWithdrawRespBO(Result result, String reqNo) {
        UnFreezeWithdrawRespBO unFreezeTransferRespBO = new UnFreezeWithdrawRespBO();
        unFreezeTransferRespBO.setRequestNo(reqNo);
        buildResponse(unFreezeTransferRespBO, result);
        log.debug("账务解冻提现调用响应：{}", unFreezeTransferRespBO);
        return unFreezeTransferRespBO;
    }

    /**
     * 封装响应
     *
     * @param accountRespBO     账务响应
     * @param result            result
     */
    private static void buildResponse(AccountRespBO accountRespBO, Result result){
        accountRespBO.setErrorCode(result.getErrorCode());
        accountRespBO.setErrorMsg(result.getErrorMsg());
        accountRespBO.setRealRtn(true);
        accountRespBO.setStatus(PayStatusEnums.FAIL.getCode());
    }

    /**
     * 获取清分响应对象
     *
     * @param result    结果
     * @return          clearFundResBO
     */
    public static ClearFundResBO getClearFundResBO(Result result){
        ClearFundResBO clearFundResBO = new ClearFundResBO();
        clearFundResBO.setPayStat(PayStatusEnums.INIT.getCode());
        clearFundResBO.setErrorCode(result.getErrorCode());
        clearFundResBO.setErrorMsg(result.getErrorMsg());
        log.debug("获取清分响应对象 错误码:{}, 错误描述:{}", result.getErrorCode(), result.getErrorMsg());

        return clearFundResBO;
    }

    /**
     * 获取清分返回对象
     *
     * @param payDTO            支付响应对象
     * @return                  clearFundBasBO
     */
    public static ClearFundResBO getClearFundResBO(PayRespDTO payDTO){
        if (payDTO == null){
            return null;
        }
        ClearFundResBO clearFundResBO = new ClearFundResBO();
        clearFundResBO.setEventNo(payDTO.getEventNo());
        clearFundResBO.setBankName(payDTO.getBankName());
        boolean realFlag = getRealFlag(payDTO.getStatus());
        clearFundResBO.setRealFlag(realFlag);
        clearFundResBO.setPayStat(realFlag ? payDTO.getStatus(): PayStatusEnums.INIT.getCode());
        clearFundResBO.setResponseDate(payDTO.getResponseDate());
        clearFundResBO.setResponseNo(payDTO.getBankFlowNo());
        clearFundResBO.setErrorCode(payDTO.getErrorCode());
        clearFundResBO.setErrorMsg(payDTO.getErrorMsg());
        clearFundResBO.setAmt(payDTO.getAmt());

        return clearFundResBO;
    }

    /**
     * 获取真实结果
     *
     * @param status            清分状态
     * @return                  true:真实;false:不真实
     */
    private static boolean getRealFlag(String status){
        return ClearStatusEnum.S.getCode().equals(status) || ClearStatusEnum.F.getCode().equals(status);
    }

    /**
     * 远程调用时出现异常
     */
    public static <T> Result<T> buildError(Exception e){
        if (ExceptionUtil.dealTimeOutException(e)) {
            return new Result<>(PayCoreErrorCode.REMOTE_SERVICE_TIME_OUT);
        }
        return new Result<>(PayCoreErrorCode.REMOTE_SERVICE_INVOKE_EXCEPTION);
    }
}
